package com.yj.core.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyStore;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * RestTemplateConfig
 *
 * @author cyj
 * @date 19-4-9
 */
//@Configuration
@Slf4j
public class RestTemplateConfig {

    @Value("${system.rest-template.ssl.key-store:}")
    private String keyStore;

    @Value("${system.rest-template.ssl.key-store-type:}")
    private String keyStoreType;

    @Value("${system.rest-template.ssl.key-store-password:}")
    private String keyStorePassword;

    @Value("${system.rest-template.ssl.connection-request-timeout:3000}")
    private Integer connectionRequestTimeout;

    @Value("${system.rest-template.ssl.connect-timeout:3000}")
    private Integer connectTimeout;

    @Value("${system.rest-template.ssl.read-timeout:3000}")
    private Integer readTimeout;

    @Value("${system.rest-template.ssl.max-pool-http-client-connection:200}")
    private Integer maxPoolHttpClientConnection;


    @Bean
    public RestTemplate restTemplate() throws Exception {
        Boolean openHttps = false;

        ClassPathResource clientResource = null;
        try {
            clientResource = new ClassPathResource(keyStore);
            clientResource.getFile();
            openHttps = true;
        } catch (Exception e){
            log.error("未加载到https相关证书文件,默认不开启https");
        }

        if (StringUtils.isNotBlank(keyStore) && openHttps){
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setConnectionRequestTimeout(connectionRequestTimeout);
            factory.setConnectTimeout(connectTimeout);
            factory.setReadTimeout(readTimeout);

            // 1 设置客户端证书
            KeyStore selfCert = KeyStore.getInstance(keyStoreType);
            selfCert.load(clientResource.getInputStream(), keyStorePassword.toCharArray());

            SSLContext sslcontext = SSLContexts.custom()
                    //忽略掉对服务器端证书的校验
                    .loadTrustMaterial(new TrustStrategy() {
                        @Override
                        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                            return true;
                        }
                    })
                    //加载服务端提供的truststore(如果服务器提供truststore的话就不用忽略对服务器端证书的校验了)
                    //.loadTrustMaterial(new File("D:\\truststore.jks"), "123456".toCharArray(),
                    //        new TrustSelfSignedStrategy())
                    .loadKeyMaterial(selfCert, keyStorePassword.toCharArray())
                    .build();

            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
                    sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier());

            CloseableHttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(sslConnectionSocketFactory)
                    .build();

            factory.setHttpClient(httpClient);
            RestTemplate restTemplate = new RestTemplate(factory);
            clientResource.getInputStream().close();

            return restTemplate;
        } else {
            return new RestTemplate();
        }
    }
}
